<html>
    <head>
    <link rel="stylesheet" href="lmm.css" type="text/css" />
    </head>
<body class="lmm">
<!-- This file is part of the Lisp Machine manual.	-*-Text-*- -->

<!-- Still need explanation of states in general, and of RG-style error checking. -->
<!-- Need examples! -->

<div class='chapter'>4. Stack Groups</div><p class='cindent'><!-- "stack group" -->

	A <font class="italic">stack group</font> (usually abbreviated "SG") is a type of Lisp
object useful for implementation of certain advanced control structures
such as coroutines and generators.  A stack group represents a
computation and its internal state, including the Lisp stack.
At any time, the computation being
performed by the Lisp Machine is associated with one stack group,
called the <font class="italic">current</font> or <font class="italic">running</font> stack group.  The operation of
making some stack group be the current stack group is called a
<font class="italic">resumption</font> or a <font class="italic">stack group switch</font>; the running stack group is
said to have <font class="italic">resumed</font> the new stack group.  The <font class="italic">resume</font> operation
has two parts: first, the state of the running computation is saved
away inside the current stack group, and secondly the state saved in
the new stack group is restored, and the new stack group is made
current.  Then the computation of the new stack group resumes its
course.

	The stack group remembers all functions which
were active at the time of the resumption (that is, the running
function, its caller, its caller's caller, etc.), and where
in each function the computation was up to.  In other words,
the entire control stack (or regular pdl) is saved.  In addition,
the bindings that were present are saved also; that is, the environment
stack (or special pdl) is saved.  When the state of the current
stack group is saved away, all of its bindings are undone,
and when the state is restored, the bindings are put back.
Note that although bindings are temporarily undone, unwind-protect
handlers are <font class="italic">not</font> run (see <font class="lisp">let-globally</font>).

	There are several ways that a resumption can happen.  First of all,
there are several Lisp functions, described below, which resume some
other stack group.  When some stack group (call it <font class="lisp">c</font>) calls such a
function, it is suspended in the state of being in the middle of a call
to that function.  When someone eventually resumes <font class="lisp">c</font>, the function
will return.  The arguments to these functions and the returned values
can therefore be used to pass information back and forth between stack
groups.  Secondly, if an error is signalled, the current stack group
resumes an error handler stack group, which handles the error in some
way.  Thirdly, a <font class="italic">sequence break</font> can happen, which  transfers
control to a special stack group called the <font class="italic">scheduler</font> (see (scheduler)).

	Note: the following discussion of resumers is incomplete, and the
way they work is being changed anyway.

<p class='cindent' id='stack-group'><!-- resumer -->
	Each stack group has a <font class="italic">resumer</font>.  <font class="italic">c</font>'s resumer is some other
stack group, which essentially is the last stack group to resume <font class="italic">c</font>.
This is not completely right, however, because some resume-forms set the
resumed stack group's resumer, and some don't.  So <font class="italic">c</font>'s resumer is actually
the last stack group to resume <font class="italic">c</font> by means of one of the types of
resume-form which does set the resumer.

.defvar si:%current-stack-group-previous-stack-group
The binding of this variable is the resumer of the current stack group.
.end_defvar

	There are currently four kinds of resume-forms:
.table 1
.item 1)
If <font class="italic">c</font> calls <font class="italic">s</font> as a function with an argument <font class="italic">x</font>, then <font class="italic">s</font> is resumed,
and the object transmitted is <font class="italic">x</font>.  <font class="italic">s</font>'s resumer is now <font class="italic">c</font>.
.item 2)
If <font class="italic">c</font> evaluates <font class="lisp">(stack-group-return <font class="italic">x</font>)</font>, then its resumer
is resumed, and the object transmitted is <font class="italic">x</font>.  The resumer's resumer
is not affected.
.item 3)
If <font class="italic">c</font> evaluates <font class="lisp">(stack-group-resume <font class="italic">s</font> <font class="italic">x</font>)</font>, then
<font class="italic">c</font> is resumed, and the object transmitted is <font class="italic">x</font>.  <font class="italic">c</font>'s resumer
is not affected.  (This is not currently implemented.)
.item 4)
If the initial function of <font class="italic">c</font> attempts to return a value <font class="italic">x</font>,
the regular kind of Lisp function return cannot take place, since
the function did not have any caller (it got there when the stack group
was initialized).  So instead of returning, its resumer is resumed, and
the value transmitted is <font class="italic">x</font>.  The resumer's resumer is not affected.
<font class="italic">c</font> is left in a state from which it cannot be resumed again; any
attempt to resume it would signal an error.
.end_table
	There is one other way a stack group can be resumed.  If the
running stack group <font class="italic">c</font> gets a microcode trap, then the error handler
stack group is resumed.  The object transmitted is <font class="lisp">nil</font>, and the
error handler's resumer is set to <font class="italic">c</font>.  This kind of resuming will
only happen to the error handler, so regular programs should not see
it.

<div class='section'>4.1 What is Going On Inside</div>
	The stack group itself holds a great deal of state information.
First of all, it contains the control stack, or "regular PDL".  The
control stack is what you are shown by the backtracing commands of the
error handler (currently the Control-B and Meta-B commands); it
remembers the function which is running, its caller, its caller's
caller, and so on, and remembers the point of execution of each function
(i.e. the "return addresses" of each function).
Secondly, it contains the environment stack, or "special PDL".
This contains all of the values saved by <font class="lisp">lambda</font>-binding.  Finally,
it contains various internal state information (contents of machine
registers and so on).

	When one stack group resumes a second, the first thing that
happens is that (some of) the state of the processor is saved in the
first stack group.  Next, all of the bindings in effect are undone;
each stack group has its own environment, and the bindings done in one
stack group do not affect another stack group at all.  Then the second
stack group's bindings are restored, its machine state is restored, and
the second stack group proceeds from where it left off.  While these
things are happening, the transmitted object is passed into the second
stack group, and optionally the second stack group's resumer is made
to be the first stack group.


<!-- More narrative here. -->

.defvar si:%current-stack-group
The value of <font class="lisp">si:%current-stack-group</font> is the stack group which is
currently running.  A program can use this variable to get its hands
on its own stack group.
.end_defvar

<div class='defun'><font class='exdent'><font class='funcname'>make-stack-group <font class='italic' color='purple'>name &optional options</font></font></font><br>
This creates and returns a new stack group.  <font class="italic">name</font> may be any symbol; it is used
to identify and print the stack group.  Each option is a keyword followed by
a value for that option; any number of options may be given, including zero.
The options are not too useful; most calls to
<font class="lisp">make-stack-group</font> don't have any options at all.
The options are:
.table 3
.item :sg-area
The area in which to create the stack group structure itself.
Defaults to <font class="lisp">default-array-area</font>.
.item :regular-pdl-area
The area in which to create the regular PDL.  Note that this
may not be any area; only certain areas may hold regular PDL,
because accessing a regular PDL as memory must go through special
microcode which checks an internal cache called the <font class="italic">pdl buffer</font>.
<!-- Just what needs to be true of the area? -->
Defaults to <font class="lisp">error-linear-pdl-area</font>.
.item :special-pdl-area
The area in which to create the special PDL.
Defaults to <font class="lisp">default-array-area</font>.
.item :regular-pdl-size
Length of the regular PDL to be created.  Defaults to 3000.
.item :special-pdl-size
Length of the special PDL to be created.  Defaults to 400.
.item :car-sym-mode
The "error mode" which determines the action taken when there
is an attempt to apply <font class="lisp">car</font> to a symbol.  This, and the other
"error mode" options, are documented with the fucntions <font class="lisp">car</font>
and <font class="lisp">cdr</font>.  Defaults to <font class="lisp">1</font>.
.item :car-num-mode
As above, for applying <font class="lisp">car</font> to a number.  Defaults to 0.
.item :cdr-sym-mode
As above, for applying <font class="lisp">cdr</font> to a symbol.  Defaults to 1.
.item :cdr-num-mode
As above, for applying <font class="lisp">cdr</font> to a number.  Defaults to 0.
.item :swap-sv-on-call-out
.item :swap-sv-of-sg-that-calls-me
.item :trap-enable
This determines what to do if a microcode error occurs.
If it is <font class="lisp">1</font> the system tries to handle the error;
if it is <font class="lisp">0</font> the machine halts.  Defaults to 1.
.item :safe
If <font class="lisp">1</font> (the default), a strict call-return discipline among
stack-groups is enforced.  If <font class="lisp">0</font>, no restriction on stack-group
switching is imposed.
<!-- I could explain this a lot better if I understood it. -->
.end_table
</div>

<div class='defun'><font class='exdent'><font class='funcname'>stack-group-preset <font class='italic' color='purple'>stack-group function &rest arguments</font></font></font><br>
This sets up <font class="italic">stack-group</font> so that when it is resumed,
<font class="italic">function</font> will be applied to <font class="italic">arguments</font> within the stack group.
Both stacks are made empty.
<font class="lisp">stack-group-preset</font> is used to initialize a stack group just after it is made,
but it may be done to any stack group at any time.
</div>

<div class='defun'><font class='exdent'><font class='funcname'>stack-group-return <font class='italic' color='purple'>x</font></font></font><br>
Let <font class="italic">s</font> be the current stack group's resumer;
<font class="lisp">stack-group-return</font> will resume <font class="italic">s</font>, transmitting
the value <font class="italic">x</font>.  <font class="italic">s</font>'s resumer is not affected.
</div>

<div class='defun'><font class='exdent'><font class='funcname'>stack-group-resume <font class='italic' color='purple'>s x</font></font></font><br>
<font class="lisp">stack-group-resume</font>
will resume <font class="italic">s</font>, transmitting the object <font class="italic">x</font>.  <font class="italic">s</font>'s
resumer is not affected.  This function is not currently implemented.
</div>

<!-- Add some discussion of the screws Gosper encountered.  Discuss how -->
<!-- stack-groups relate to variables, environments, conditions, throws, etc. -->

.eof
</body>
</html>

